package org.mobilesynergies.epic.client.parameter;
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/* 
 * This file was taken from The Android Open Source Project and modified.
 * Originally it was the Bundle data structure.
 * Android specifics have been removed to make it useful in a broader context.
 * 
 */


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.mobilesynergies.epic.client.EpicFormField;
import org.mobilesynergies.epic.client.Log;




/**
 * A composite data structure that holds a mapping from strings to various data types. 
 *
 */
public class ParameterMap {//extends Parameter{
	private static final String LOG_TAG = "ParameterMap";

	

	/**
	 * The map holding the data
	 */
	Map<String, Parameter> mMap = null;


	/**
	 * Constructs a new, empty ParameterMap.
	 */
	public ParameterMap() {
		mMap = new LinkedHashMap<String, Parameter>();
	}


	/**
	 * Constructs a new, empty ParameterMap sized to hold the given number of
	 * elements. The ParameterMap will grow as needed.
	 *
	 * @param capacity the initial capacity of the ParameterMap
	 */
	/*public ParameterMap(int capacity) {
		mMap = new TreeMap<String, Parameter>(capacity);
	}*/

	/**
	 * Constructs a ParameterMap containing a copy of the mappings from the given
	 * ParameterMap.
	 *
	 * @param b a ParameterMap to be copied.
	 */
	public ParameterMap(ParameterMap b) {

		if (b.mMap != null) {
			mMap = new LinkedHashMap<String, Parameter>(b.mMap);
		} else {
			mMap = null;
		}
	}


	/**
	 * Extracts the information of the form and creates a ParameterMap from it. All previously contained Parameters are erased from the map.
	 * @param form The input for the new map
	 * @return 
	 */
	public void initializeFromForm(Form form) {
		mMap.clear();
		if(form!=null){
			LinkedHashMap<String, UnknownParameter> mapParameters = new LinkedHashMap<String, UnknownParameter>(); 
			Iterator<FormField> iterFields = form.getFields();
			while(iterFields.hasNext()) {
				FormField field = iterFields.next();
				String variable = field.getVariable();
				String label = field.getLabel();
				String type = field.getType();
				Iterator<String> values = field.getValues();
				String[] specialization = variable.split("_");
				
				UnknownParameter p = null;
				if( ! mapParameters.containsKey(specialization[0]))
				{
					p = new UnknownParameter();
					mapParameters.put(specialization[0], p);
					
				} else {
					p = mapParameters.get(specialization[0]);
				}
				
				if(specialization.length==1) {
					p.insert(Parameter.KEY_NAME, specialization[0]);
					if(values.hasNext()){
						String value = values.next();
						p.insert(Parameter.KEY_VALUE, value);
					}

				} else if (specialization.length == 2) {
					if(values.hasNext()){
						String value = values.next();
						p.insert(specialization[1], value);
					}
				} else {
					System.out.println("Unexpected behaviour when transforming a Form to a ParameterMap: A FormField contained multiple underscore ('_') characters.");
				}
			}
			
			Collection<UnknownParameter> collectionParams = mapParameters.values();
			Iterator<UnknownParameter> iterParams = collectionParams.iterator();
			while(iterParams.hasNext()){
				UnknownParameter p = iterParams.next();
				if(p.containsKey(Parameter.KEY_NAME)) {
					String name = p.get(Parameter.KEY_NAME);
					try{
						putParameter(name, Parameter.createParameter(p.getMap()));
					} catch (ParameterException e) {
						e.printStackTrace();
					}
				} else {
					System.out.println("Error: converting FormField to Parameter");
				}
				
			}
		}
	}

	/*@Override
	public String toXml(String name) {
		String type = "ParameterMap";
		String value = "";

		Set<String> keys = mMap.keySet();
		Iterator<String> iterKeys = keys.iterator();
		while(iterKeys.hasNext()) {
			String nameOfChild = iterKeys.next();
			Parameter p = mMap.get(nameOfChild);
			if(p!=null) {
				value += p.toXml(nameOfChild);
			}
		}

		String extraattributes = null;
		String extraxml = null;
		return toXml(name, type, value, extraattributes, extraxml);
	}*/


	/**
	 * Clones the current ParameterMap. The internal map is cloned, but the keys and
	 * values to which it refers are copied by reference.
	 */
	@Override
	public Object clone() {
		return new ParameterMap(this);
	}


	/**
	 * Returns the number of mappings contained in this ParameterMap.
	 *
	 * @return the number of mappings as an int.
	 */
	public int size() {
		return mMap.size();
	}

	/**
	 * Returns true if the mapping of this ParameterMap is empty, false otherwise.
	 */
	public boolean isEmpty() {
		return mMap.isEmpty();
	}

	/**
	 * Removes all elements from the mapping of this ParameterMap.
	 */
	public void clear() {
		mMap.clear();
	}

	public Map<String,Parameter> getMap(){
		return mMap;
	}

	/**
	 * Returns true if the given key is contained in the mapping
	 * of this ParameterMap.
	 *
	 * @param key a String key
	 * @return true if the key is part of the mapping, false otherwise
	 */
	public boolean containsKey(String key) {
		return mMap.containsKey(key);
	}

	/**
	 * Returns the entry with the given key as an Parameter.
	 *
	 * @param key a String key
	 * @return an Object, or null
	 */
	public Parameter get(String key) {
		return mMap.get(key);
	}

	/**
	 * Removes any entry with the given key from the mapping of this ParameterMap.
	 *
	 * @param key a String key
	 */
	public void remove(String key) {
		mMap.remove(key);
	}

	/**
	 * Inserts all mappings from the given ParameterMap into this ParameterMap.
	 *
	 * @param map a ParameterMap
	 */
	public void putAll(ParameterMap map) {
		mMap.putAll(map.mMap);
	}

	/**
	 * Returns a Set containing the Strings used as keys in this ParameterMap.
	 *
	 * @return a Set of String keys
	 */
	public Set<String> keySet() {
		return mMap.keySet();
	}

	/**
	 * Inserts a Boolean value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a Boolean, or null
	 */
	public void putBoolean(String key, boolean value) {
		mMap.put(key, new BooleanParameter(value));
	}

	/*
	 * Inserts a byte value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value a byte
	 
	public void putByte(String key, byte value) {
		mMap.put(key, new ByteParameter(value));
	}
	*/

	/*
	 * Inserts a char value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value a char, or null
	 
	public void putChar(String key, char value) {
		mMap.put(key, new CharParameter(value));
	}*/

	/*
	 * Inserts a short value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value a short
	 
	public void putShort(String key, short value) {
		mMap.put(key, new ShortParameter(value));
	}*/

	/**
	 * Inserts an int value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value an int, or null
	 */
	public void putInt(String key, int value) {
		mMap.put(key, new IntParameter(value));
	}

	/*
	 * Inserts a long value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value a long
	 
	public void putLong(String key, long value) {
		mMap.put(key, new LongParameter(value));
	}*/

	/**
	 * Inserts a float value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value a float
	 */
	public void putFloat(String key, float value) {
		mMap.put(key, new FloatParameter(value));
	}

	/*
	 * Inserts a double value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.
	 *
	 * @param key a String, or null
	 * @param value a double
	 
	public void putDouble(String key, double value) {
		mMap.put(key, new DoubleParameter(value));
	}*/

	/**
	 * Inserts a String value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a String, or null
	 */
	public void putString(String key, String value) {
		mMap.put(key, new StringParameter(value));
	}

	/* Not implemented in the current version
	 * 
	 * Inserts a CharSequence value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a CharSequence, or null

    public void putCharSequence(String key, CharSequence value) {
        mMap.put(key, value);
    }
	 */

	/*
	 * Inserts an ArrayList<Integer> value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value an ArrayList<Integer> object, or null
	 
	public void putIntegerArrayList(String key, ArrayList<Integer> value) {
		mMap.put(key, new IntegerArrayParameter(value));
	}*/

	/*
	 * Inserts an ArrayList<String> value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value an ArrayList<String> object, or null
	 
	public void putStringArrayList(String key, ArrayList<String> value) {
		mMap.put(key, new StringArrayParameter(value));
	}*/

	/**
	 * Inserts a Parameter into the mapping if this ParameterMap, replacing any existing value for the given key.
	 * @param key a String or null
	 * @param param a Parameter object, or null
	 */
	public void putParameter(String key, Parameter param) {
		mMap.put(key, param);		
	}


	/* Not implemented in the current version
	 * 
	 * Inserts a Serializable value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a Serializable object, or null

    public void putSerializable(String key, Serializable value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * 
	 * 
	 * Inserts a boolean array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a boolean array object, or null

    public void putBooleanArray(String key, boolean[] value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * 
	 * Inserts a byte array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a byte array object, or null

    public void putByteArray(String key, byte[] value) {
        mMap.put(key, value);
    }*/

	/* Not implemented in the current version
	 * Inserts a short array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a short array object, or null

    public void putShortArray(String key, short[] value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * Inserts a char array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a char array object, or null

    public void putCharArray(String key, char[] value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * 
	 * Inserts an int array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value an int array object, or null

    public void putIntArray(String key, int[] value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * 
	 * Inserts a long array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a long array object, or null

    public void putLongArray(String key, long[] value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * 
	 * Inserts a float array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a float array object, or null

    public void putFloatArray(String key, float[] value) {
        mMap.put(key, value);
    }*/

	/* Not implemented in the current version
	 * 
	 * Inserts a double array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a double array object, or null

    public void putDoubleArray(String key, double[] value) {
        mMap.put(key, value);
    }
	 */

	/* Not implemented in the current version
	 * 
	 * Inserts a String array value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a String array object, or null

    public void putStringArray(String key, String[] value) {
        mMap.put(key, value);
    }*/

	/*  Not implemented in the current version
	 * Inserts a ParameterMap value into the mapping of this ParameterMap, replacing
	 * any existing value for the given key.  Either key or value may be null.
	 *
	 * @param key a String, or null
	 * @param value a ParameterMap object, or null
	 
	public void putParameterMap(String key, ParameterMap value) {
		mMap.put(key, value);
	}
	*/



	// Log a message if the value was non-null but not of the expected type
	private void typeWarning(String key, Object value, String className,
			Object defaultValue, ClassCastException e) {
		StringBuilder sb = new StringBuilder();
		sb.append("Key ");
		sb.append(key);
		sb.append(" expected ");
		sb.append(className);
		sb.append(" but value was a ");
		sb.append(value.getClass().getName());
		sb.append(".  The default value ");
		sb.append(defaultValue);
		sb.append(" was returned.");
		Log.w(LOG_TAG, sb.toString());
		Log.w(LOG_TAG, "Attempt to cast generated internal exception:", e);
	}

	private void typeWarning(String key, Object value, String className,
			ClassCastException e) {
		typeWarning(key, value, className, "<null>", e);
	}


	/**
	 * Returns the value associated with the given key, or false if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a boolean value
	 */
	public boolean getBoolean(String key) {
		return getBoolean(key, false);
	}


	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a boolean value
	 */
	public boolean getBoolean(String key, boolean defaultValue) {
		Parameter o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return ((BooleanParameter) o).getValue();
		} catch (ClassCastException e) {
			typeWarning(key, o, "BooleanParameter", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or (byte) 0 if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a byte value
	 */
	public byte getByte(String key) {
		return getByte(key, (byte) 0);
	}

	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a byte value
	 */
	public Byte getByte(String key, byte defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return (Byte) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "Byte", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or false if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a char value
	 */
	public char getChar(String key) {
		return getChar(key, (char) 0);
	}

	/**
	 * Returns the value associated with the given key, or (char) 0 if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a char value
	 */
	public char getChar(String key, char defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return (Character) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "Character", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or (short) 0 if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a short value
	 */
	public short getShort(String key) {
		return getShort(key, (short) 0);
	}

	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a short value
	 */
	public short getShort(String key, short defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return (Short) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "Short", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or 0 if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return an int value
	 */
	public int getInt(String key) {
		return getInt(key, 0);
	}

	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return an int value
	 */
	public int getInt(String key, int defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return ((IntParameter) o).getValue();
		} catch (ClassCastException e) {
			typeWarning(key, o, "IntParameter", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or 0L if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a long value
	 */
	public long getLong(String key) {
		return getLong(key, 0L);
	}

	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a long value
	 */
	public long getLong(String key, long defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return (Long) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "Long", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or 0.0f if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a float value
	 */
	public float getFloat(String key) {
		return getFloat(key, 0.0f);
	}

	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a float value
	 */
	public float getFloat(String key, float defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return ((FloatParameter)o).getValue();
		} catch (ClassCastException e) {
			typeWarning(key, o, "FloatParameter", defaultValue, e);
			return defaultValue;
		}
	}

	/**
	 * Returns the value associated with the given key, or 0.0 if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a double value
	 */
	public double getDouble(String key) {
		return getDouble(key, 0.0);
	}

	/**
	 * Returns the value associated with the given key, or defaultValue if
	 * no mapping of the desired type exists for the given key.
	 *
	 * @param key a String
	 * @return a double value
	 */
	public double getDouble(String key, double defaultValue) {
		Object o = mMap.get(key);
		if (o == null) {
			return defaultValue;
		}
		try {
			return (Double) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "Double", defaultValue, e);
			return defaultValue;
		}
	}


	/**
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a String value, or null
	 */
	public String getString(String key) {
		Object o = mMap.get(key);
		if (o == null) {
			return null;
		}
		try {
			return ((StringParameter) o).getValue();
		} catch (ClassCastException e) {
			typeWarning(key, o, "StringParameter", e);
			return null;
		}
	}

	/**
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a CharSequence value, or null
	 */
	public CharSequence getCharSequence(String key) {
		Object o = mMap.get(key);
		if (o == null) {
			return null;
		}
		try {
			return (CharSequence) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "CharSequence", e);
			return null;
		}
	}

	/**
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a ParameterMap value, or null
	 */
	public ParameterMap getParameterMap(String key) {
		Object o = mMap.get(key);
		if (o == null) {
			return null;
		}
		try {
			return (ParameterMap) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "ParameterMap", e);
			return null;
		}
	}


	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a Serializable value, or null

    public Serializable getSerializable(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (Serializable) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Serializable", e);
            return null;
        }
    }*/

	/**
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return an ArrayList<String> value, or null
	 */
	public ArrayList<Integer> getIntegerArrayList(String key) {
		Object o = mMap.get(key);
		if (o == null) {
			return null;
		}
		try {
			return (ArrayList<Integer>) o;
		} catch (ClassCastException e) {
			typeWarning(key, o, "ArrayList<Integer>", e);
			return null;
		}
	}

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return an ArrayList<String> value, or null

    public ArrayList<String> getStringArrayList(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (ArrayList<String>) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "ArrayList<String>", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a boolean[] value, or null

    public boolean[] getBooleanArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (boolean[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "byte[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a byte[] value, or null

    public byte[] getByteArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (byte[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "byte[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a short[] value, or null

    public short[] getShortArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (short[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "short[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a char[] value, or null

    public char[] getCharArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (char[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "char[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return an int[] value, or null

    public int[] getIntArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (int[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "int[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a long[] value, or null

    public long[] getLongArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (long[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "long[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a float[] value, or null

    public float[] getFloatArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (float[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "float[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a double[] value, or null

    public double[] getDoubleArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (double[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "double[]", e);
            return null;
        }
    }*/

	/* Not implemented in the current version
	 * 
	 * Returns the value associated with the given key, or null if
	 * no mapping of the desired type exists for the given key or a null
	 * value is explicitly associated with the key.
	 *
	 * @param key a String, or null
	 * @return a String[] value, or null

    public String[] getStringArray(String key) {
        Object o = mMap.get(key);
        if (o == null) {
            return null;
        }
        try {
            return (String[]) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "String[]", e);
            return null;
        }
    }*/

	/*@Override
	public int getType() {
		return Parameter.TYPE_PARAMETERMAP;
	}*/


	public void createForm(Form form) {
		Set<String> keys =  keySet();
		if(keys.isEmpty()) {
			return;
		} else {

			Iterator<String> iterKeys = keys.iterator();
			while(iterKeys.hasNext()) {
				String key = iterKeys.next();
				Parameter parameter = get(key);
				if(parameter != null) {
					EpicFormField formField = new EpicFormField(key, parameter);
					Set<FormField> fields = formField.getFields();
					Iterator<FormField> iterFields = fields.iterator();
					while(iterFields.hasNext()){
						form.addField(iterFields.next());
					}
				}
			}
		}
	}
	
	public void fillForm(Form form) {
		Set<String> keys =  keySet();
		if(keys.isEmpty()) {
			return;
		} else {
			Iterator<String> iterKeys = keys.iterator();
			while(iterKeys.hasNext()) {
				String key = iterKeys.next();
				Parameter parameter = get(key);
				if(parameter != null) {
					//we treat boolean variables differently
					if(parameter.getType().equalsIgnoreCase(Parameter.TYPENAME_BOOLEAN)) {
						boolean bValue = ((BooleanParameter)parameter).getValue();
						form.setAnswer(key, bValue);						
					} else {
						form.setAnswer(key, parameter.getValueAsString());
					}
				}
			}
		}
	}

	/*@Override
	public Set<FormField> toFormFields(String name) {
		Set<FormField> setResult = new HashSet<FormField>();
		
		FormField field = new FormField(name);
		field.setType(TYPE_NAME);
		field.setLabel(name);
		setResult.add(field);
		
		
		Set<String> keys =  keySet();
		if(! keys.isEmpty()) {
		} else {
			Iterator<String> iterKeys = keys.iterator();
			//for each parameter in the map
			while(iterKeys.hasNext()) {
				String key = iterKeys.next();
				Parameter p = get(key);
				//we create a hierarchical name structure
				Set<FormField> setParameter = p.toFormFields(name+"."+key);
				Iterator<FormField> iterParameterFormFields = setParameter.iterator();
				//for each form field of the parameter
				while(iterParameterFormFields.hasNext()){
					setResult.add(iterParameterFormFields.next());
				}
			}
		}
		return setResult;
	}*/


}
